<?php

use GatewayWorker\Lib\Gateway;

class Events
{
    // 数据库配置（请根据实际环境修改）
    private static $dbConfig = [
        'host' => '8.138.148.243',
        'user' => 'sql782388',
        'password' => 'sql782388',
        'dbname' => 'didi',
        'port' => 3306,
        'charset' => 'utf8mb4'
    ];

    /**
     * 当客户端连接时触发
     */
    public static function onConnect($client_id)
    {
        echo "Client {$client_id} connected\n";
    }

    /**
     * 当客户端发来消息时触发
     */
    public static function onMessage($client_id, $message)
    {
        if ($message === 'ping') {
            Gateway::sendToClient($client_id, 'pong');
            return;
        }

        $data = json_decode($message, true);
        if (!$data) {
            Gateway::sendToClient($client_id, json_encode([
                'type' => 'error',
                'code' => 400,
                'message' => '无效的JSON格式'
            ]));
            return;
        }

        switch ($data['type']) {
            case 'login':
                self::handleLogin($client_id, $data);
                break;
            case 'location_check':
                self::handleLocationCheck($client_id, $data);
                break;
        }
    }

    /**
     * 处理登录请求
     */
    private static function handleLogin($client_id, $data)
    {
        $uid = isset($data['uid']) ? $data['uid'] : 0;
        if (!$uid) {
            Gateway::sendToClient($client_id, json_encode([
                'type' => 'login_failed',
                'message' => '用户ID不能为空'
            ]));
            return;
        }

        Gateway::bindUid($client_id, $uid);
        echo "Client {$client_id} bound to uid {$uid}\n";
        Gateway::sendToClient($client_id, json_encode([
            'type' => 'login_success',
            'message' => "绑定成功: uid={$uid}"
        ]));
    }

    /**
     * 处理位置检查请求
     */
    private static function handleLocationCheck($client_id, $data)
    {
        try {
            // 验证必要参数
            $required = ['lat', 'lng'];
            foreach ($required as $field) {
                if (!isset($data[$field]) || empty($data[$field])) {
                    Gateway::sendToClient($client_id, json_encode([
                        'type' => 'location_check',
                        'code' => 400,
                        'message' => "参数缺失: {$field}",
                        'data' => []
                    ]));
                    return;
                }
            }
            //根据经纬度链表查询job_id
            $jobIds = [];
            $allJobs = self::getAllJobs($data['user_id']);
            $userLat = (float)$data['lat'];
            $userLng = (float)$data['lng'];

            // 更新用户定位信息到 map_location 字段
            if (isset($data['user_id']) && isset($data['lat']) && isset($data['lng'])) {
                $mapLocation = $data['lat'] . ',' . $data['lng'];
                $conn = self::getDbConnection();
                if ($conn) {
                    $stmt = $conn->prepare("UPDATE di_user SET map_location = ? WHERE id = ?");
                    $stmt->bind_param("si", $mapLocation, $data['user_id']);
                    $stmt->execute();
                    $stmt->close();
                    $conn->close();
                }
            }
            foreach ($allJobs as $job) {
                $distance = self::calculateDistance($job['lat'], $job['lng'], $userLat, $userLng);
                if ($distance <= 10000000) {

                    // 验证job_id参数
                    if (!isset($job['id']) || !is_numeric($job['id'])) {
                        Gateway::sendToClient($client_id, json_encode([
                            'type' => 'location_check',
                            'code' => 400,
                            'message' => '无效的job_id参数',
                            'data' => []
                        ]));
                        return;
                    }

                    // 获取任务位置信息和详细数据
                    $jobData = self::getJobLocation((int)$job['id']); // 显式转换为整数
                    if (!$jobData) {
                        Gateway::sendToClient($client_id, json_encode([
                            'type' => 'location_check',
                            'code' => 404,
                            'message' => '任务不存在或位置信息未设置',
                            'data' => []
                        ]));
                        return;
                    }

                    // 计算距离
                    $distance = self::calculateDistance(
                        $jobData['lat'],
                        $jobData['lng'],
                        (float)$data['lat'],
                        (float)$data['lng']
                    );

                    // 判断是否在打卡范围内
                    $inRange = $distance <= 100; // 100米范围内可打卡
                    
                    // 检查任务是否在开始时间一小时内（只允许开始时间之后的一小时内打卡）
                    $currentTime = time();
                    $startTime = strtotime($jobData['start_time']);
                    $withinOneHour = $currentTime >= $startTime && ($currentTime - $startTime) <= 3600; // 只允许在开始时间之后1小时内打卡
                    
                    if($inRange){
                        if (!$withinOneHour) {
                            // 不在任务开始时间之后一小时内，不允许打卡
                            Gateway::sendToClient($client_id, json_encode([
                                'type' => 'location_check',
                                'code' => 400,
                                'message' => '只允许在任务开始时间之后一小时内打卡',
                                'data' => []
                            ]));
                            continue;
                        }
                        
                        // 检查用户自动签到状态
                        $autoSignIn = self::checkAutoSignInStatus($data['user_id']);
                        if ($autoSignIn) {
                            $inRange = false;//已开始自动打卡隐藏手动打卡
                            // 自动签到，无需额外操作
                            $conn = self::getDbConnection();
                            if (!$conn) return false;
                            $stmt = $conn->prepare("UPDATE di_user_orders SET status = 2 WHERE user_id = ? AND job_id = ?");
                            $stmt->bind_param("ii", $data['user_id'], $job['id']);
                            $stmt->execute();
                            
                            $stmt->close();
                            $conn->close();
                             Gateway::sendToClient($client_id, json_encode([
                                'type' => 'location_check_qiandao',
                                'code' => 200,
                                'message' => '自动签到成功,任务id：'.$job['id'],
                                'data' => []
                            ]));
                        } else {
                            // 非自动签到，需要提示用户签到
                            Gateway::sendToClient($client_id, json_encode([
                                'type' => 'location_check',
                                'code' => 200,
                                'message' => '未签到，请签到',
                                'data' => []
                            ]));
                            
                        }
                    }
                    // 获取任务状态文本
                    $statusText = self::getStatusText($jobData['status']);

                    // 返回结果，包含完整任务信息
                    Gateway::sendToClient($client_id, json_encode([
                        'type' => 'location_check',
                        'code' => 200,
                        'message' => $$distance <= 100 ? '已在打卡范围内' : '未在打卡范围内',
                        'data' => [
                            'in_range' => $inRange,
                            'distance' => round($distance, 2),
                            'job_id' => $jobData['id'],
                            'task_name' => $jobData['name'],
                            'task_status' => $jobData['status'],
                            'task_status_text' => $statusText,
                            'task_end_time' => $jobData['end_time'],
                            'task_location' => $jobData['address'] // 原始位置字符串
                        ]
                    ]));
                }
            }
            if (empty($allJobs)) {
                Gateway::sendToClient($client_id, json_encode([
                    'type' => 'location_check',
                    'code' => 200,
                    'message' => '当前没有任务',
                    'user_id' => $data['user_id'],
                    'lat' => $data['lat'],
                    'lng' => $data['lng'],
                    'data' => []
                ]));
            }
        } catch (\Exception $e) {
            Gateway::sendToClient($client_id, json_encode([
                'type' => 'location_check',
                'code' => 500,
                'message' => $e->getMessage(),
                'data' => []
            ]));
        }
    }

     /**
     * 检查用户自动签到状态
     */
    private static function checkAutoSignInStatus($userId)
    {
        $conn = self::getDbConnection();
        if (!$conn) return false;

        // 修改SQL查询，获取更多任务信息
        $stmt = $conn->prepare("SELECT qiandao FROM di_user WHERE id = " . $userId);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows !== 1) {
            $stmt->close();
            $conn->close();
            return false;
        }

        $user = $result->fetch_assoc();
        $stmt->close();
        $conn->close();

        return $user['qiandao'];
    }

    /**
     * 从数据库获取任务位置信息和详细数据
     */
    private static function getJobLocation($jobId)
    {
        $conn = self::getDbConnection();
        if (!$conn) return false;

        // 修改SQL查询，获取更多任务信息
        $stmt = $conn->prepare("SELECT * FROM di_part_time_jobs WHERE id = " . $jobId);

        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows !== 1) {
            $stmt->close();
            $conn->close();
            return false;
        }

        $job = $result->fetch_assoc();
        $stmt->close();
        $conn->close();

        // 解析位置信息
        $location = explode(',', $job['map_location'] ?? '0,0');
        return [
            'lat' => (float)$location[0],
            'lng' => (float)$location[1],
            'name' => $job['title'] ?? '未知任务',
            'start_time' => $job['start_time'] ?? '',
            'end_time' => $job['end_time'] ?? '',
            'status' => $job['status'] ?? 0,
            'id' => $job['id'] ?? 0,
            'address' => $job['address'] ?? ''
        ];
    }

    /**
     * 创建数据库连接
     */
    private static function getDbConnection()
    {
        $config = self::$dbConfig;
        $conn = new mysqli(
            $config['host'],
            $config['user'],
            $config['password'],
            $config['dbname'],
            $config['port']
        );

        if ($conn->connect_error) {
            echo "数据库连接失败: " . $conn->connect_error . "\n";
            return false;
        }

        $conn->set_charset($config['charset']);
        return $conn;
    }

    /**
     * 计算两点间距离(米)
     */
    private static function calculateDistance($lat1, $lng1, $lat2, $lng2)
    {
        $earthRadius = 6371000; // 地球半径(米)

        $latFrom = deg2rad($lat1);
        $lonFrom = deg2rad($lng1);
        $latTo = deg2rad($lat2);
        $lonTo = deg2rad($lng2);

        $latDelta = $latTo - $latFrom;
        $lonDelta = $lonTo - $lonFrom;

        $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
            cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));

        return $angle * $earthRadius;
    }

    /**
     * 当用户断开连接时触发
     */
    public static function onClose($client_id)
    {
        $uid = Gateway::getUidByClientId($client_id);
        if ($uid) {
            Gateway::unbindUid($client_id, $uid);
            echo "Client {$client_id} unbound from uid {$uid}\n";
        }
        echo "Client {$client_id} closed\n";
    }


    /**
     * 获取任务状态文本描述
     */
    private static function getStatusText($status)
    {
        $statusMap = [
            1 => '待接单',
            2 => '已接单',
            3 => '进行中',
            4 => '已完成',
            5 => '已取消'
        ];
        return $statusMap[$status] ?? '未知状态';
    }

    /**
     * 获取所有任务的基础信息
     */
    private static function getAllJobs($user_id)
    {
        $conn = self::getDbConnection();
        if (!$conn) return [];

        $stmt = $conn->query("SELECT di_part_time_jobs.id,di_part_time_jobs.map_location FROM di_user_orders
         left join di_part_time_jobs on di_user_orders.job_id = di_part_time_jobs.id 
         WHERE di_user_orders.user_id = {$user_id} AND di_user_orders.status = 1");

        if (!$stmt) {
            $conn->close();
            return [];
        }

        $jobs = [];
        while ($job = $stmt->fetch_assoc()) {
            $location = explode(',', $job['map_location'] ?? '0,0');
            $jobs[] = [
                'id' => $job['id'],
                'lat' => (float)$location[0],
                'lng' => (float)$location[1]
            ];
        }

        $stmt->close();
        $conn->close();
        return $jobs;
    }
}

// CREATE TABLE `di_part_time_jobs` (
//   `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
//   `type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '兼职类型(单选):general=常规兼职（发传单、搬家等）,food_wish=美食心愿（探寻心中想要的美食）,companion=寻求陪伴（约酒局、聊天散心、精神慰藉）,medical_aid=医护协助（健康饮食定制、物资代购配送、顾问式护理等）,emergency=紧急发布（救助老人摔倒、紧急事情发布，最长30分钟达）',
//   `job_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '兼职类型',
//   `address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '地点位置',
//   `map_location` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地图经纬度',
//   `start_time` datetime NOT NULL COMMENT '开始时间',
//   `end_time` datetime NOT NULL COMMENT '结束时间',
//   `skill_desc` text COLLATE utf8mb4_unicode_ci COMMENT '技能描述',
//   `person_req` text COLLATE utf8mb4_unicode_ci COMMENT '人员要求',
//   `people_num` int(11) NOT NULL COMMENT '人数',
//   `contact_phone` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系电话',
//   `salary` decimal(10,2) NOT NULL COMMENT '报酬',
//   `create_time` int(10) unsigned NOT NULL COMMENT '创建时间',
//   `update_time` int(10) unsigned NOT NULL COMMENT '更新时间',
//   `delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
//   `user_id` int(10) unsigned DEFAULT '0' COMMENT '用户ID',
//   `status` int(10) DEFAULT '1',
//   `title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '标题',
//   PRIMARY KEY (`id`),
//   KEY `idx_create_time` (`create_time`),
//   KEY `idx_delete_time` (`delete_time`)
// ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='兼职发布信息表';


// CREATE TABLE `di_user_orders` (
//   `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
//   `user_id` int(10) unsigned NOT NULL COMMENT '用户ID（关联 fa_user 表）',
//   `job_id` int(10) unsigned NOT NULL COMMENT '兼职任务ID（关联 fa_part_time_jobs 表）',
//   `order_time` int(10) unsigned NOT NULL COMMENT '接单时间（时间戳）',
//   `salary` decimal(10,2) NOT NULL COMMENT '接单时的报酬（冗余存储，避免任务表修改影响）',
//   `status` tinyint(2) NOT NULL DEFAULT '1' COMMENT '状态：1=已接单, 2=进行中, 3=待验收, 4=已完成, 5=取消',
//   `create_time` int(10) unsigned NOT NULL COMMENT '创建时间',
//   `update_time` int(10) unsigned NOT NULL COMMENT '更新时间',
//   `delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间（软删除标记）',
//   PRIMARY KEY (`id`),
//   UNIQUE KEY `uk_user_task` (`user_id`,`job_id`) COMMENT '同一用户不可重复接同一任务',
//   KEY `idx_part_time` (`job_id`),
//   KEY `idx_order_time` (`order_time`),
//   KEY `idx_status` (`status`)
// ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户接单信息表';


// CREATE TABLE `di_user_orders` (
//   `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
//   `user_id` int(10) unsigned NOT NULL COMMENT '用户ID（关联 fa_user 表）',
//   `job_id` int(10) unsigned NOT NULL COMMENT '兼职任务ID（关联 fa_part_time_jobs 表）',
//   `order_time` int(10) unsigned NOT NULL COMMENT '接单时间（时间戳）',
//   `salary` decimal(10,2) NOT NULL COMMENT '接单时的报酬（冗余存储，避免任务表修改影响）',
//   `status` tinyint(2) NOT NULL DEFAULT '1' COMMENT '状态：1=已接单, 2=进行中, 3=待验收, 4=已完成, 5=取消',
//   `create_time` int(10) unsigned NOT NULL COMMENT '创建时间',
//   `update_time` int(10) unsigned NOT NULL COMMENT '更新时间',
//   `delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间（软删除标记）',
//   PRIMARY KEY (`id`),
//   UNIQUE KEY `uk_user_task` (`user_id`,`job_id`) COMMENT '同一用户不可重复接同一任务',
//   KEY `idx_part_time` (`job_id`),
//   KEY `idx_order_time` (`order_time`),
//   KEY `idx_status` (`status`)
// ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户接单信息表';